<template>
  <PageWrapper v-loading="false" loading-tip="加载中...">
    <div class="p-4 p-4-tag">
      <div class="main-nav">
        <BasicForm @register="registerForm" />
        <div class="btns">
          <a-button
            class="btns-one"
            @click="throttleStop"
            :disabled="!loading"
            :loading="loadingByStop"
            >停止查找</a-button
          >
          <a-button type="primary" @click="throttleSubmit" :loading="loading">查找</a-button>
        </div>
      </div>
      <div class="main-content">
        <div class="table-style">
          <BasicTable
            :columns="columns"
            :loading="loading"
            @register="registerTable"
            :dataSource="tableData.list"
            :canResize="false"
            :showIndexColumn="false"
            :rowSelection="{ type: 'radio' }"
            :striped="true"
            :bordered="true"
            :pagination="false"
            @selection-change="handleSelectChange"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="targetKeys.indexOf(column.key) >= 0">
                <a-tooltip placement="top">
                  <template #title>
                    <span>{{ record[column.key] }}</span>
                  </template>
                  <div class="value-style" @dblclick="handleDbClick(record[column.key])">{{
                    record[column.key]
                  }}</div>
                </a-tooltip>
              </template>
            </template>

            <template #toolbar>
              <a-button type="primary" @click="handleOpen" v-if="hasPermission('5-1-add')"
                >新增节点</a-button
              >
              <a-button
                type="primary"
                :disabled="isDisabled"
                @click="handleOpenDownLoad"
                v-if="hasPermission('5-1-download')"
                >下载工程</a-button
              >
              <a-button
                type="primary"
                @click="throttleByUpload"
                :disabled="isDisabled"
                :loading="loadingByUpload"
                v-if="hasPermission('5-1-upload')"
                >上传工程</a-button
              >
              <a-button
                type="primary"
                @click="handleDetail"
                :disabled="isDisabledByDetail"
                v-if="hasPermission('5-1-look')"
                >详情</a-button
              >
              <a-button
                type="primary"
                :disabled="isDisabled"
                :loading="loadingByRestart"
                @click="throttleByRestart"
                v-if="hasPermission('5-1-restart')"
              >
                重启节点</a-button
              >
              <BasicUpload
                v-if="hasPermission('5-1-update')"
                :disabled="isDisabled"
                :maxSize="50"
                :maxNumber="1"
                :uploadBtn="{
                  txt: '软件更新',
                  title: '软件更新',
                  type: 'primary',
                  preIcon: '',
                  disabled: isDisabled,
                }"
                :api="uploadApi"
                :isShowThumb="false"
                :uploadParams="{
                  Parameters: `['${tagretInfo.data.IPV4}']`,
                  Controller: 'GatewayManager',
                  Action: 'SoftwareUpdates',
                }"
                :showPreviewNumber="false"
                :emptyHidePreview="true"
                class="my-5"
              />
            </template>
          </BasicTable>
        </div>
        <!-- <div class="flex py-2 items-center justify-end pagination-box">
          <a-pagination
            :show-total="(total) => `共 ${total} 条数据`"
            showSizeChanger
            size="small"
            :current="paginationInfo.data.current"
            :pageSize="paginationInfo.data.pageSize"
            :total="paginationInfo.data.total"
            @change="handlePageChange"
          />
        </div> -->
      </div>
    </div>
    <modelByDetail
      @register="registerByDetail"
      @submit-success="handleUpdateTable"
      :ips="tagretInfo.ips"
    />
    <modelByInfo @register="registerByInfo" @close-sync="handleCloseInfo" :info="tagretInfo.data" />

    <modelByDownLoad
      @register="registerByDownLoad"
      @submit-success="handleDownLoadSuccess"
      :info="tagretInfo.data"
    />
  </PageWrapper>
</template>

<script setup lang="ts">
  import { usePermission } from '/@/hooks/web/usePermission';
  import { PageWrapper } from '/@/components/Page';
  import { ref, reactive, onMounted, nextTick, h, unref, onBeforeUnmount } from 'vue';
  import { useDebounceFn } from '@vueuse/core';
  import { BasicTable, useTable } from '/@/components/Table';
  import { BasicColumn } from '/@/components/Table/src/types/table';
  import { Tooltip } from 'ant-design-vue';
  import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { checkIp } from '/@/utils/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { downloadByData, getFileHash } from '/@/utils/file/download';
  import { BasicUpload } from '/@/components/Upload';
  import modelByDetail from '/@/views/project/gateway/components/modelByDetail.vue';
  import modelByInfo from '/@/views/project/gateway/components/modelByInfo.vue';

  import modelByDownLoad from '/@/views/project/gateway/components/modelByDownLoad.vue';

  import { useModal } from '/@/components/Modal';
  import { uploadApi } from '/@/api/system/index';
  import {
    getNodeSearchModes,
    startScanNode,
    stopScanNode,
    restartIOTService,
    projectuploading,
    getupdatenode,
    getipv4address,
    // softwareupdates,
  } from '/@/api/gateway/index';

  const ATooltip = Tooltip;
  let loading = ref(false);
  let loadingByStop = ref(false);
  let isDisabled = ref(true);
  let isDisabledByDetail = ref(true);
  const { hasPermission } = usePermission();
  let loadingByUpload = ref(false);
  let loadingByRestart = ref(false);
  // let loadingByUpdate = ref(false);
  let targetKeys = ['SN', 'MachineName', 'IPV4', 'ProjectName', 'ProjectFullPath'];
  let tagretInfo = reactive({
    ips: [],
    data: {},
  });
  let tableData = reactive({
    list: [],
  });
  // 计时器
  let intervalID: any = '';

  const { createConfirm, createMessage } = useMessage();
  const { clipboardRef, copiedRef } = useCopyToClipboard();

  // 分页信息
  let paginationInfo = reactive({
    data: {
      pageSize: 50,
      total: 0,
      current: 1,
    },
  });
  const schemas: FormSchema[] = [
    {
      field: 'searchMethod',
      component: 'Select',
      label: '查找方式：',
      colProps: {
        span: 24,
      },
      defaultValue: 0,
      componentProps: {
        placeholder: '请选择查找方式',
        options: [],
        allowClear: false,
        fieldNames: { label: 'Name', value: 'Value', key: 'Key' },
      },
    },
    {
      field: 'startIP',
      component: 'Input',
      label: '起始IP：',
      ifShow: ({ values }) => {
        return values.searchMethod === 1;
      },
      colProps: {
        span: 24,
      },
      defaultValue: '',
      componentProps: {
        placeholder: '请输入起始IP',
      },
      rules: [
        {
          required: true,
          validator: async (_rule, value) => checkIp(value, '起始IP'),
          trigger: ['change', 'blur'],
        },
        {
          required: true,
          validator: async (_rule, value) => checkIpBy127(value),
          trigger: ['change', 'blur'],
        },
      ],
    },
    {
      field: 'endIP',
      component: 'Input',
      label: '结束IP：',
      ifShow: ({ values }) => {
        return values.searchMethod === 1;
      },
      colProps: {
        span: 24,
      },
      defaultValue: '',
      componentProps: {
        placeholder: '请输入结束IP',
      },
      rules: [
        {
          required: true,
          validator: async (_rule, value) => checkIp(value, '结束IP'),
          trigger: ['change', 'blur'],
        },
      ],
    },
  ];
  // 表格数据
  let columns: BasicColumn[] = [
    {
      title: 'SN',
      dataIndex: 'SN',
      width: 250,
    },
    {
      title: '电脑名称',
      dataIndex: 'MachineName',
      width: 250,
    },
    {
      title: 'IP',
      dataIndex: 'IPV4',
    },
    {
      title: '设备状态',
      dataIndex: 'IsRunningCn',
    },
    {
      title: '工程名称',
      dataIndex: 'ProjectName',
      width: 250,
    },
    {
      title: '工程路径',
      dataIndex: 'ProjectFullPath',
      width: 250,
    },
    {
      title: 'IOT版本',
      dataIndex: 'Version',
    },
    {
      title: '系统版本',
      dataIndex: 'OSVersion',
      width: 250,
    },
    {
      title: '驱动授权数',
      dataIndex: 'NumberOfDriverLicenses',
    },
  ];
  const [registerForm, { updateSchema, validateFields }] = useForm({
    labelWidth: 90,
    schemas: schemas,
    showActionButtonGroup: false,
    actionColOptions: {
      span: 24,
    },
  });

  const [registerTable, { clearSelectedRowKeys }] = useTable();
  const [registerByDetail, { openModal: openModalByDetail, closeModal: closeModalByDetail }] =
    useModal();
  const [registerByDownLoad, { openModal: openModalByDownLoad, closeModal: closeModalByDownLoad }] =
    useModal();
  const [registerByInfo, { openModal: openModalByInfo }] = useModal();
  const throttleSubmit = useDebounceFn(handleSubmint, 500);
  const throttleStop = useDebounceFn(handleStop, 500);
  const throttleByRestart = useDebounceFn(handleRestart, 500);
  const throttleByUpload = useDebounceFn(handleUpload, 500);
  async function handleDbClick(val) {
    const value = unref(val);
    clipboardRef.value = value;
    if (unref(copiedRef)) {
      createMessage.success('复制成功');
    }
  }

  function checkIpBy127(value) {
    if (value.indexOf(127) >= 0) {
      return Promise.reject('不能输入127开头的ip地址');
    }
    return Promise.resolve();
  }
  function handleCloseInfo() {
    isDisabled.value = true;
    isDisabledByDetail.value = true;
    clearSelectedRowKeys();
    tagretInfo.ips = [];
    tagretInfo.data = {
      IPV4: '',
    };
  }

  async function handleDetail(_record) {
    openModalByInfo();
  }
  // 获取节点最新数据
  async function getupdatenodeFn() {
    let ips = tableData.list.map((item) => item.IPV4);
    try {
      let res = await getupdatenode([ips]);
      tableData.list.forEach((v) => {
        let targetVals = res.filter((val) => val.IPV4 === v.IPV4);
        if (targetVals.length > 0) v = targetVals[0];
      });
    } catch (error) {
      if (intervalID) clearInterval(intervalID);
    }
  }
  // 启动轮询
  function startIntercal() {
    if (intervalID) clearInterval(intervalID);
    intervalID = setInterval(() => {
      getupdatenodeFn();
    }, 15000);
  }

  async function handleUpload() {
    createConfirm({
      iconType: 'warning',
      okText: '确认',
      title: () => h('span', '温馨提示'),
      content: () => h('span', `是否确认上传工程（IP：${tagretInfo.data.IPV4}）`),
      onOk: async () => {
        loadingByUpload.value = true;
        try {
          let res = await projectuploading([tagretInfo.data.IPV4, tagretInfo.data.ProjectFullPath]);
          const blob = new Blob([res.data], { type: 'application/octet-stream' });
          let hash = await getFileHash(blob);
          let resHash = res.headers['FileSHA'] || res.headers['filesha'] || '';
          let contentDisposition =
            res.headers['Content-Disposition'] || res.headers['content-disposition'] || '';
          let getFileTypes = contentDisposition.split('filename=*');
          if (hash === resHash) {
            if (getFileTypes.length < 2) {
              createMessage.warning('无法获取文件后缀，请联系开发人员');
              loadingByUpload.value = false;
            } else {
              downloadByData(res.data, `${tagretInfo.data.ProjectName}${getFileTypes[1]}`);
            }
          } else {
            createMessage.warning('文件数据缺失，请重新下载');
          }
          loadingByUpload.value = false;
        } catch (error) {
          loadingByUpload.value = false;
        }
      },
    });
  }

  async function handleRestart() {
    createConfirm({
      iconType: 'warning',
      okText: '确认',
      title: () => h('span', '温馨提示'),
      content: () => h('span', `是否确认重启该节点（${tagretInfo.data.IPV4}）`),
      onOk: async () => {
        loadingByRestart.value = true;
        try {
          await restartIOTService([tagretInfo.data.IPV4, '手动重启']);
          createMessage.success('正在重启，请稍后刷新页面');
          loadingByRestart.value = false;
        } catch (error) {
          loadingByRestart.value = false;
        }
      },
    });
  }

  // async function handleUpdate() {
  //   createConfirm({
  //     iconType: 'warning',
  //     okText: '确认',
  //     title: () => h('span', '温馨提示'),
  //     content: () => h('span', `是否确认软件更新（${tagretInfo.data.IPV4}）`),
  //     onOk: async () => {
  //       loadingByUpdate.value = true;
  //       try {
  //         await softwareupdates([tagretInfo.data.IPV4, tagretInfo.data.ProjectFullPath]);
  //         createMessage.success('节点软件更新成功');
  //         loadingByUpdate.value = false;
  //       } catch (error) {
  //         loadingByUpdate.value = false;
  //       }
  //     },
  //   });
  // }
  async function handleStop() {
    loadingByStop.value = true;
    try {
      await stopScanNode();
      loading.value = false;
      loadingByStop.value = false;
      clearSelectedRowKeys();
      tagretInfo.ips = [];

      tagretInfo.data = {
        IPV4: '',
      };
    } catch (_e) {
      loadingByStop.value = false;
    }
  }
  function handleSubmint() {
    paginationInfo.data.current = 1;
    paginationInfo.data.total = 0;
    clearSelectedRowKeys();
    tagretInfo.ips = [];

    tagretInfo.data = {
      IPV4: '',
    };
    getTableData();
  }
  function handleSelectChange(val) {
    let { rows } = val;

    let obj = rows.length > 0 ? rows[0] : {};
    tagretInfo.ips = [];

    tagretInfo.data = obj;
    isDisabledByDetail.value = obj.key ? false : true;
    isDisabled.value = obj.key && obj.IsRunning ? false : true;
  }
  // function handlePageChange(page, pageSize) {
  //   paginationInfo.data.current = page;
  //   paginationInfo.data.pageSize = pageSize;
  //   // setTagList();
  // }
  async function getTableData() {
    try {
      loading.value = true;
      let searchForm = await validateFields();
      let res = await startScanNode([
        searchForm.searchMethod,
        +searchForm.searchMethod === 1 ? searchForm.startIP : '',
        +searchForm.searchMethod === 1 ? searchForm.endIP : '',
        // {
        //   //分页的对象
        //   PageNO: paginationInfo.data.current,
        //   PageSize: paginationInfo.data.pageSize,
        // },
      ]);
      // paginationInfo.data.total = res.TotalRows;
      tableData.list = res.map((item) => {
        item.IsRunningCn =
          ['', null, undefined].indexOf(item.IsRunning) >= 0
            ? ''
            : item.IsRunning
            ? '在线中'
            : '已离线';
        return item;
      });
      startIntercal();
      loading.value = false;
    } catch (error) {
      loading.value = false;
    }
  }
  async function getNodeSearchModesFn() {
    let res = await getNodeSearchModes();
    nextTick(() => {
      updateSchema({
        field: 'searchMethod',
        componentProps: {
          options: res || [],
        },
      });
    });
  }
  function handleOpenDownLoad() {
    openModalByDownLoad();
  }
  function handleDownLoadSuccess() {
    closeModalByDownLoad();
    isDisabled.value = true;
    isDisabledByDetail.value = true;
    clearSelectedRowKeys();
    tagretInfo.ips = [];

    tagretInfo.data = {
      IPV4: '',
    };
  }
  function handleOpen() {
    tagretInfo.ips = tableData.list.map((item) => item.IPV4);

    openModalByDetail();
  }
  function handleUpdateTable(value) {
    let newVal = JSON.parse(JSON.stringify(value.val));
    let newTableData = JSON.parse(JSON.stringify(tableData.list));
    if (newVal.IPV4) {
      newVal.IsRunningCn =
        ['', null, undefined].indexOf(newVal.IsRunning) >= 0
          ? ''
          : newVal.IsRunning
          ? '在线中'
          : '已离线';
      let isExist = newTableData.filter((item) => item.IPV4 === newVal.IPV4).length > 0;
      if (!isExist) newTableData = [...[newVal], ...newTableData];

      tableData.list = newTableData;
      startIntercal();
    }

    closeModalByDetail();
  }
  async function getipv4addressFn() {
    let res = await getipv4address();
    let val = res
      .split('.')
      .filter((_v, i) => i <= 2)
      .join('.');
    if (val) {
      nextTick(() => {
        updateSchema({
          field: 'startIP',
          defaultValue: val + '.1',
        });
        updateSchema({
          field: 'endIP',
          defaultValue: val + '.254',
        });
      });
    }
  }
  onMounted(async () => {
    getNodeSearchModesFn();
    getipv4addressFn();
    // getTableData();
  });
  onBeforeUnmount(() => {
    if (intervalID) clearInterval(intervalID);
  });
</script>

<style lang="less" scoped>
  .p-4-tag {
    width: 100%;
    height: 100%;
    padding: 0px !important;
    position: relative;

    .main-nav {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      background-color: #fff;
      width: 320px;
      overflow-x: hidden;
      overflow-y: auto;
      padding: 10px 10px;
      box-sizing: border-box;
    }

    .main-content {
      position: absolute;
      top: 0;
      left: 330px;
      bottom: 0;
      right: 0;
      overflow-y: hidden;
      background-color: #fff;
      padding-bottom: 42px;

      .table-style {
        height: 100%;
        overflow-y: auto;
      }

      .pagination-box {
        z-index: 9;
        padding: 10px 5px;
        box-sizing: border-box;
        position: absolute;
        width: 100%;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: #fff;
      }
    }

    .btns {
      width: 100%;
      padding-left: 90px;
      box-sizing: border-box;

      .btns-one {
        margin-right: 10px;
      }
    }
  }

  .value-style {
    cursor: pointer;
    width: 100%;

    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -khtml-user-select: none;
    user-select: none;
  }
</style>
